home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Reference Guide / C-C++ Interactive Reference Guide.iso / c_ref / csource4 / 203_01 / yam7.c < prev    next >
Text File  |  1979-12-31  |  39KB  |  1,623 lines

  1. /*
  2. $title ('yam7.c: file i/o, initialization')
  3. $date (11 NOV 85)
  4. */
  5. /*
  6.  * File open and close stuff and more ...
  7.  * This file has been modified for operation on a MS-DOS system
  8.  */
  9.  
  10. #include <dos.h>
  11. #include "yam.h"
  12. #include <fcntl.h>
  13.  
  14. /* globals used by dodir */
  15. unsigned Numfiles;  /* Total number of files expanded */
  16. unsigned Blocks;   /* Number of records */
  17.  
  18. /* following are MSDOS system calls */
  19. #define COMPFILSIZ 0x23    /* compute file size */
  20. #define CHANGEDIR 0x3B    /* change current directory */
  21. #define FINDFIRST 0x4E    /* bdos search for file pattern*/
  22. #define FINDNEXT 0x4F    /* search for next occurrence */
  23. #define GETDEFDISK 0x19    /* get current disk */
  24. #define GETFREE 0x36    /* get free disk space */
  25. #define SELDSK 0x0E        /* bdos select disk 0=default disk */
  26. #define SETDMA 0x1A        /* set address for read, write, etc. */
  27. #define DIRAT 0x10        /* directory attribute for file searches */
  28. #define ARCHIVE 0x20    /* archive bit */
  29. #define NOTFOUND 18        /* file not found in search */
  30. #define CHATTRIB 0x43    /* change attribute */
  31. #define CARRYFLG 0x01
  32.  
  33. extern char *getenv();
  34.  
  35. /****************************************************************************
  36. FUNCTION:
  37.     get an single char from console.  Display it as entered.
  38.  
  39. CALLING PARAMETERS:
  40.     none
  41.  
  42. RETURNED PARAMETERS:
  43.     character value typed on console
  44. ===========================================================================*/
  45. char getopt()
  46. {
  47.     char c;
  48.  
  49.         /* note: if <ctype.h> included, tolower lattice c function makes
  50.            this routine request double entrys for each char. */
  51.     c = tolower(getcty());
  52.     putcty(c);
  53.     return c;
  54. } /* getopt */
  55.  
  56.  
  57. /****************************************************************************
  58. FUNCTION:
  59.     open a file for receive.  This file will be written to.
  60.  
  61. CALLING PARAMETERS:
  62.     pathname:
  63.         pointer to ascii file pathname representation
  64. ===========================================================================*/
  65. openrx(pathname)
  66. char *pathname;
  67. {
  68.     char option;
  69. #ifdef RESTRICTED
  70.     char *s;
  71.  
  72.     /* no garbage names please */
  73.     for(s=pathname; *s; )
  74.         if(*s++ > 'z')
  75.             return ERROR;
  76. #endif
  77.     unspace(pathname);
  78.         /* show the name right away */
  79.     printf("'%s' ", pathname);
  80.  
  81.         /* open file for read.  If exists, allow option to overwrite */
  82.     if(!Creamfile && ((fout=fopen(pathname,"r")) != NULL))
  83.     {
  84.             /* close file if successful open */
  85.         fclose(fout);
  86. #ifdef XMODEM
  87.         printf("Can't upload: file exists\n");
  88.         return ERROR;
  89. #else
  90.         printf("Exists, Replace/Append/Quit (r/a/q)?");
  91.         option=getopt();
  92.         if(!index(option, "ary"))
  93.             return ERROR;
  94. #endif
  95.     }
  96.     if(option=='a')
  97.         fout=fopen(pathname,"ab+");
  98.     else
  99.         fout=fopen(pathname,"wb");
  100.     if (fout==NULL)
  101.     {
  102.         printf(" Can't create\n");
  103.         return ERROR;
  104.     }
  105.         /* receive file is open */
  106.     Rfile= TRUE;
  107.     strcpy(Rname, pathname);
  108.  
  109.         /* Dumping means term input will go to disk.  Squelch allows this
  110.            to be turned on and off.  Why I don't know. */
  111.     Dumping = !Squelch;
  112.     printf(" Open\n");
  113. #ifdef STATLINE
  114.     lpstat("Receiving %s", Rname);
  115. #endif
  116.     return OK;
  117. }
  118.  
  119.  
  120. /****************************************************************************
  121. FUNCTION:
  122.     close receive data file
  123.  
  124. CALLING PARAMETERS:
  125.     pad:
  126.         sets pad for log file
  127. ===========================================================================*/
  128. closerx(pad)
  129. {
  130.         /* close only if sucessful open */
  131.     if(Rfile)
  132.     {
  133.             /* flush all buffers before closing */
  134.         fflush(fout);
  135.         fclose(fout);
  136.         Rfile=FALSE;
  137. #ifdef LOGRX
  138.         logfile(LOGRX, Rname, pad?'*':'R');    /* record file xmsn */
  139. #endif
  140.     }
  141. }
  142.  
  143.  
  144. /****************************************************************************
  145. FUNCTION:
  146.     get file size and return number bytes occupied by file
  147.  
  148. CALLING PARAMETERS:
  149.     *pathname:
  150.         pointer to file pathname.
  151. ===========================================================================*/
  152. long getfilesize(pathname)
  153. char *pathname;
  154. {
  155.     struct find_buf f_buf;
  156.     union REGS inregs;
  157.     union REGS outregs;
  158.  
  159.         /* DMA must point to f_buf structure */
  160.     bdos(SETDMA, &f_buf);
  161.         /* set pointer to file name */
  162.     inregs.x.dx = (short)pathname;
  163.         /* find first DOS function */
  164.     inregs.h.ah = FINDFIRST;
  165.         /* allow search for files only */
  166.     inregs.x.cx = DIRAT;
  167.  
  168.         /* dos request function */
  169.     intdos(&inregs,&outregs);
  170.     if (outregs.h.al != NULL)
  171.         return NULL;
  172.  
  173.         /* return number of blocks used by file */
  174.     return f_buf.filesize;
  175. } /* getfilesize */
  176.  
  177.  
  178. /****************************************************************************
  179. FUNCTION:
  180.     open a file for transmission to a remote
  181.  
  182. CALLING PARAMETERS:
  183.     mode:
  184.         0=don't compute file size
  185.         1=compute file size
  186.         >1=use file size already computed in f_buf
  187.     f_buf:
  188.         pointer to a structure containing information about file. if
  189.         0 routine will not report file transmission time.  If 1, file
  190.         size must be calculated, otherwise the structure is already
  191.         initialized.
  192.     *pathname:
  193.         pointer to a string representing file name to be opened
  194. ===========================================================================*/
  195. opentx(mode,f_buf,pathname)
  196. struct find_buf *f_buf;
  197. char *pathname;
  198. int mode;
  199. {
  200.     int blocks;
  201.     long bytes;
  202.  
  203.         /* set file name into global buffer */
  204.     unspace(pathname);
  205.     strcpy(Tname, pathname);
  206.  
  207.     printf("'%s' ", pathname);
  208.     if((fin=fopen(pathname,"rb"))==NULL)
  209.     {
  210.         printf("Can't open\n");
  211.         return ERROR;
  212.     }
  213.     printf("Open\n");
  214.  
  215. #ifdef RESTRICTED
  216.             /* restriced file stuff needs to be added */
  217.         fclose(fin);
  218.         printf("Not for Distribution\n");
  219.         return ERROR;
  220. #endif
  221.  
  222.         /* transmit file is open */
  223.     Tfile= TRUE;
  224.  
  225.         /* compute file size. mode will <> NULL when f_buf it is initialized
  226.            by another routine */
  227.     if (mode == 1)
  228.         bytes = getfilesize(pathname);
  229.     else if (mode != NULL)
  230.         bytes = f_buf->filesize;
  231.  
  232.         /* display download time */
  233.     blocks = (int)(bytes/blklen + (bytes%blklen?1:0));
  234.     if (mode != NULL)
  235.         dis_xmit_time(1,blocks);
  236.  
  237.     return OK;
  238. } /* opentx */
  239.  
  240.  
  241. /****************************************************************************
  242. FUNCTION:
  243.     display transmission time of a file
  244.  
  245. CALLING PARAMETERS:
  246.     nfiles:
  247.         number of file(s) to be sent
  248.     blks:
  249.         number of blks occupied by file(s)
  250. ===========================================================================*/
  251. dis_xmit_time(nfiles,blks)
  252. unsigned nfiles;
  253. unsigned blks;
  254. {
  255.     unsigned spm;
  256.     unsigned dminutes;
  257.  
  258.         /* sector per minute */
  259.         /* (Baudrate*60)/(10 bits each char * 136 chars) */
  260.     spm = Baudrate/23;
  261.  
  262.         /* download minutes calculation */
  263.     dminutes = nfiles+((10*(nfiles+blks))/spm)+(blks/20);
  264.  
  265.         /* display computed transmission time */
  266.         /* display number and size.  #k/s = 128b/s / 1024b/k = 1/8 */
  267.     printf("%u Blocks %dk %u.%u Minutes Xmsn Time at %u Baud\n",
  268.         blks, blks/8, dminutes/10, dminutes%10, Baudrate);
  269.  
  270.     /* display file name, length and minutes for transfer on status line */
  271. #ifdef STATLINE
  272.     lpstat("%s %u Blocks %dk %u.%u Min",
  273.         Tname, blks, blks/8, dminutes/10, dminutes%10);
  274. #endif
  275. } /* dis_xmit_time */
  276.  
  277.  
  278. /****************************************************************************
  279. FUNCTION:
  280.     closetx(status) call with status != 0 if incomplete file xmsn
  281.  
  282. CALLING PARAMETERS:
  283.     status:
  284.         if false and LOGTX, will call logfile with Tname
  285. ===========================================================================*/
  286. closetx(status)
  287. {
  288.     if(Tfile)
  289.     {
  290.         fclose(fin);
  291. #ifdef LOGTX
  292.         if(!status)
  293.             logfile(LOGTX, Tname, 's');    /* record file xmsn */
  294. #endif
  295.         Tfile=FALSE;
  296.     }
  297. } /* closetx */
  298.  
  299.  
  300. /****************************************************************************
  301. FUNCTION:
  302.     search the phone file for name
  303.  
  304. CALLING PARAMETERS:
  305.     name:
  306.         pointer to name to search for in phone file
  307.     buffer:
  308.         pointer to buffer to use to read phone file into
  309.  
  310. RETURNED PARAMETERS:
  311.     TRUE if succesful, ERROR if something went wrong
  312. ===========================================================================*/
  313. #ifdef PHONES
  314. getphone(name, buffer)
  315. char *name, *buffer;
  316. {
  317.     closetx(TRUE);
  318.  
  319.     searchpath(PHONES,Utility.ubuf);
  320.     if((fin=fopen(Utility.ubuf,"rb"))==NULL)
  321.     {
  322.         printf("Cannot open %s\n", Utility.ubuf);
  323.         return ERROR;
  324.     }
  325.     else
  326.     {
  327.         while(fgets(buffer, 100, fin))
  328.             if(cmdeq(buffer, name))
  329.             {
  330.                 fclose(fin);
  331.                 return OK;
  332.             }
  333.     }
  334.     fclose(fin);
  335.     return ERROR;
  336. } /* get phone */
  337. #endif
  338.  
  339.  
  340. /****************************************************************************
  341. FUNCTION:
  342.     change default disk.  Removed the valid disk check, let the
  343.     operating system do that.  It his job.
  344.  
  345. CALLING PARAMETERS:
  346.     p:
  347.         pointer to disk to change to.
  348. ===========================================================================*/
  349. chdsk(p)
  350. char *p;
  351. {
  352.  
  353.         /* check if file is open for transmit or receive */
  354.     if(Rfile||Tfile)
  355.     {
  356.         printf("Must close files first");
  357.         return ERROR;
  358.     }
  359.     *p=toupper(*p);
  360.     defdisk= *p - 'A';
  361.     bdos(SELDSK, defdisk);
  362.     return OK;
  363.  
  364. } /* chdsk */
  365.  
  366.  
  367. /****************************************************************************
  368. FUNCTION:
  369.     change current directory.
  370.  
  371. CALLING PARAMETERS:
  372.     ptr:
  373.         pointer to directory to change to.
  374. ===========================================================================*/
  375. chgdir(ptr)
  376. char **ptr;
  377. {
  378.     int stat;
  379.  
  380.     stat = bdos(CHANGEDIR, *ptr);
  381.     if (stat != OK)
  382.         printf("directory not found\n");
  383. } /* chdir */
  384.  
  385.  
  386. /****************************************************************************
  387. FUNCTION:
  388.     print the current working directory.
  389.  
  390. CALLING PARAMETERS:
  391.     none
  392. ===========================================================================*/
  393. dopwd()
  394. {
  395.  
  396.     union REGS inregs;
  397.     union REGS outregs;
  398.  
  399.         /* pointer to scratch buffer */
  400.     inregs.x.si = (short)&Utility.ubuf;
  401.  
  402.         /* get text of current directory */
  403.     inregs.h.ah = 0x47;
  404.  
  405.         /* use current disk */
  406.     inregs.h.dl = 0;
  407.  
  408.         /* dos request function */
  409.     intdos(&inregs,&outregs);
  410.  
  411.     if (outregs.x.ax==0x15)
  412.         printf("invalid drive\n");
  413.     else
  414.         printf("%s\n",&Utility.ubuf);
  415. } /* dopwd */
  416.  
  417.  
  418.  
  419. /****************************************************************************
  420. FUNCTION:
  421.     print string for terminals with a status line starting at column 48.
  422.     note that a call to lpstat will erase what pstat displays
  423.  
  424. CALLING PARAMETERS:
  425.     *a,*b,*c:
  426.         pointers to strings to be printed.
  427. ===========================================================================*/
  428. pstat(a,b,c)
  429. char *a, *b, *c;
  430. {
  431.     char pbuf[40];
  432.  
  433. #ifdef STATLINE
  434.     /* insert string for terminal to go to stat line, col 48 */
  435.     lputs("\0");
  436. #endif
  437.     sprintf(pbuf, a,b,c);
  438.     lputs(pbuf);
  439.  
  440.     /* insert line to go return from stat line */
  441. #ifdef STATLINE
  442.     lputs("\0");
  443. #else
  444.     printf("\n");
  445. #endif
  446. } /* pstat */
  447.  
  448.  
  449. /****************************************************************************
  450. FUNCTION:
  451.     print string for terminals with a status line starting at column 1.
  452.     Rest of line is erased
  453.  
  454. CALLING PARAMETERS:
  455.     *a...*g
  456.         pointers to strings to be printed.
  457. ===========================================================================*/
  458. lpstat(a,b,c,d,e,f,g)
  459. char *a, *b, *c, *d, *e, *f, *g;
  460. {
  461.     /* insert line to go to status line col 1 */
  462. #ifdef STATLINE
  463.     lputs("\0");
  464. #endif
  465.     printf(a,b,c,d,e,f,g);
  466.  
  467.     /* insert line to go to return from status line */
  468. #ifdef STATLINE
  469.     lputs("\0");
  470. #else
  471.     printf("\n");
  472. #endif
  473. }
  474.  
  475.  
  476. /****************************************************************************
  477. FUNCTION:
  478.     List a file to the console.  Wild card listings are allowed
  479.  
  480. CALLING PARAMETERS:
  481.     argc:
  482.         integer number of parameters at argp
  483.     **argp:
  484.         pointer to pointer to pathname for directory search
  485. ===========================================================================*/
  486. dolist(argc, argp)
  487. char **argp;
  488. int argc;
  489. {
  490.     int listfile();
  491.  
  492.     printf("^S pauses, ^X skips to next file, ^C terminates\n");
  493.     expand(listfile, argc, argp);
  494. } /* dolist */
  495.  
  496.  
  497. /****************************************************************************
  498. FUNCTION:
  499.     Display a directory of the disk.
  500.  
  501. CALLING PARAMETERS:
  502.     argc:
  503.         count of number of paramters at argp
  504.     argp:
  505.         pointer to pointer to pathname for directory search
  506. ===========================================================================*/
  507. dodir(argc, argp)
  508. char **argp;
  509. int argc;
  510. {
  511.     int pdirent();
  512.  
  513.         /* reset variables */
  514.     cfast=Numfiles=Blocks=0;
  515.  
  516.         /* do function.  error return will cause abort(such as file not
  517.            found or ^C entered on keyboard */
  518.     if (expand(pdirent, argc, argp)==ERROR)
  519.         return;
  520.  
  521.         /* make sure bytes left is on its own line */
  522.     if (cfast!=3)
  523.         putch('\n');
  524.  
  525.         /* number of total files, including directorys */
  526.     printf("%d File(s) ",Numfiles);
  527.  
  528.         /* display bytes left on disk */
  529.     printdfr();
  530.     putch('\n');
  531.  
  532.         /* display download time */
  533.     dis_xmit_time(Numfiles,Blocks);
  534.  
  535. } /* dodir */
  536.  
  537.  
  538. /****************************************************************************
  539. FUNCTION:
  540.     print directory entry left justfied in a 14 char wide field, followed
  541.     by length of file and calculated transmission time.
  542.  
  543. CALLING PARAMETERS:
  544.     f_buf:
  545.         pointer to a structure containing information about file
  546.     *pathname:
  547.         pointer to directory path name
  548. ===========================================================================*/
  549. pdirent(f_buf,pathname)
  550. struct find_buf *f_buf;
  551. char *pathname;
  552. {
  553.     long blks;
  554.  
  555.     if (f_buf->attrib & DIRAT)
  556.         printf("%-14s <DIR>    ",f_buf->pname);
  557.  
  558.         /* ignore special files */
  559.     else if ((f_buf->attrib & !ARCHIVE)==0)
  560.     {
  561.         printf("%-14s  %7ld ",f_buf->pname,f_buf->filesize);
  562.  
  563.             /* number of blklen byte records */
  564.         blks = (f_buf->filesize)/blklen;
  565.         if (f_buf->filesize % blklen)
  566.             blks++;
  567.  
  568.             /* global indication of how many files were found */
  569.         Numfiles = Numfiles + 1;
  570.  
  571.             /* total blocks */
  572.         Blocks = Blocks + (int)blks;
  573.     }
  574.  
  575.     if (++cfast==3)
  576.     {
  577.         cfast=0;
  578.         putchar('\n');
  579.     }
  580.     else
  581.         printf("| ");
  582.  
  583.         /* allow ^C to abort */
  584.     if (CIREADY && CICHAR==ETX)
  585.         return ERROR;
  586.     return OK;
  587. } /* pdirent */
  588.  
  589.  
  590. /****************************************************************************
  591. FUNCTION:
  592.     expand the requested path by pre-pending the requested search rules
  593.     as defined in the PATH environment parameter.  This allows default
  594.     files to be stored where the main program is loaded from.  The user
  595.     can then access all special files from anywhere, without being restricted
  596.     to a specific directory.  The routine creates the pathname and tries to 
  597.     open it.  If successful it returns, otherwise it creates the next pathname
  598.     and tries again.
  599.  
  600. CALLING PARAMETERS:
  601.     fname:
  602.         pointer to string representing pathname to search for
  603.     pathbuf:
  604.         pointer to buffer where resulting path name will be contructed.
  605. ===========================================================================*/
  606. searchpath(fname,pathbuf)
  607. char *fname;
  608. char *pathbuf;
  609. {
  610.     char *env;
  611.     char *eptr;
  612.     int baselen;
  613.  
  614.         /* get environent path string */
  615.     env = getenv("PATH");
  616.  
  617.         /* search for pathname separator */
  618.     eptr = env;
  619.     baselen=0;
  620.     while(1)
  621.     {
  622.         baselen++;
  623.         if ( (*++eptr == 0) || (*eptr == ';') )
  624.         {
  625.                 /* copy basename to local buffer */
  626.             movmem(env,pathbuf,baselen);
  627.             pathbuf[baselen] = '\\';
  628.             pathbuf[baselen+1] = 0;
  629.  
  630.                 /* concat file name to create full pathname */
  631.             strcat(pathbuf,fname);
  632.  
  633.                 /* if not a successful open, continue */
  634.             fin=fopen(pathbuf,"rb");
  635.             fclose(fin);
  636.             if (fin!=NULL)
  637.                 return;
  638.             
  639.                 /* reset for next interation */
  640.             baselen = 0;    
  641.  
  642.                 /* done on last string */
  643.             if (!*eptr)
  644.                 break;
  645.             env = ++eptr;
  646.         }
  647.     }
  648.         /* copy default name into buffer */
  649.     strcpy(pathbuf,fname);
  650. } /* searchpath */
  651.  
  652.  
  653. /****************************************************************************
  654. FUNCTION:
  655.     Processes a DOS pathname for ambiguous file references.  The fixed up
  656.     search path is placed in a buffer specified by the sp pointer.  The
  657.     buffer at sp will contain the input, possibly augmented with "*.*" or
  658.     "\*.*" so that it will work with the DOS FINDFIRST and FINDNEXT functions.
  659.     Basic concept stolen from Dr. Dobbs Journal, 10/85 p16.
  660.  
  661. CALLING PARAMETERS:
  662.     ip:
  663.         input path pointer
  664.     sp:
  665.         pointer to buffer to receive search path
  666.  
  667. RETURNED PARAMETERS:
  668.     ERROR if the input path should not be used, OK otherwise.
  669. ===========================================================================*/
  670. int fixpath(ip,sp)
  671. char *ip;
  672. char *sp;
  673. {
  674.     union REGS inregs;
  675.     int flags;
  676.  
  677.         /* all cases return the input string */
  678.     strcpy(sp,ip);
  679.  
  680.         /* 4 special cases:
  681.             1) null string = "*.*"
  682.             2) "x:" = "x:*.*"
  683.             3) root dir "\" which is mis-handled by MS-DOS 2.1 and 3.0
  684.             4) any reference ending in "\"    */
  685.     if ( (strlen(ip)==0)        /* null string */
  686.        ||(strcmp(ip+1,":")==0)    /* d: only */
  687.        ||(index(ip[strlen(ip)-1],PATHSEP)) )    /* ends in path separator */
  688.     {
  689.             /* add *.* for search */
  690.         strcat(sp,"*.*");
  691.         return(OK);
  692.     }
  693.  
  694.         /* non-null terminated string.  possibilities are:
  695.             1) explicit file reference
  696.             2) explicit directory reference
  697.             3) ambiguou file reference
  698.             4) unknown name
  699.            These can be separted reliably with the dos change/read attributes
  700.            function. */
  701.     inregs.h.ah = CHATTRIB;
  702.     inregs.h.al = 0;
  703.     inregs.x.dx = (short)ip;
  704.     inregs.x.cx = 0;
  705.     flags = intdos(&inregs,&inregs);
  706.  
  707.         /* final name unknown, no use to search */
  708.     if ( (flags & CARRYFLG) && (inregs.x.ax==0x0002) )
  709.         return ERROR;
  710.  
  711.         /* path not found or file is not a directory.  File open will fail
  712.            if file does not exist */
  713.     if ( ((flags & CARRYFLG)&&(inregs.x.ax==0x0003)
  714.         ||(((flags & CARRYFLG)==0)&&((inregs.x.cx & DIRAT)==0))) )
  715.     {
  716.         return OK;
  717.     }
  718.  
  719.         /* file is a directory, append "\*.*" */
  720.     if (((flags & CARRYFLG)==0)&&(inregs.x.cx & DIRAT))
  721.     {
  722.         strcat(sp,"\\*.*");
  723.         return OK;
  724.     }
  725.     else
  726.         return ERROR;
  727. } /* fixpath */
  728.  
  729.  
  730. /****************************************************************************
  731. FUNCTION:
  732.     expand an ambiguous file name, and call a function using the expanded
  733.     name.
  734.  
  735. CALLING PARAMETERS:
  736.     *fnx():
  737.         pointer to a function to call after file name is expanded.
  738.     argc:
  739.         integer count for number of argp's
  740.     argp:
  741.         pointer to pointer to arguments
  742. ===========================================================================*/
  743. expand(fnx, argc, argp)
  744. int (*fnx)();
  745. int argc;
  746. char **argp;
  747. {
  748.     char name[PATHLEN];
  749.  
  750.         /* no arguments, use *.* */
  751.     if(argc<=0)
  752.         return e1xpand(fnx, "*.*");
  753.     else
  754.         while(--argc>=0)
  755.         {
  756.                 /* expand ambiguous file name */
  757.             fixpath(*argp++,name);
  758.             return e1xpand(fnx, name);
  759.         }
  760.     return OK;
  761. } /* expand */
  762.  
  763.  
  764. /****************************************************************************
  765. FUNCTION:
  766.     e1xpand expands ambiguous pathname afnp    calling fnx for each.  Full
  767.     MS-DOS pathnames are supported.
  768.  
  769. CALLING PARAMETERS:
  770.     fnx:
  771.         pointer to function to call after file name is expanded
  772.     *afnp:
  773.         pointer to ambiguous file name
  774. ===========================================================================*/
  775. e1xpand(fnx, afnp)
  776. int (*fnx)();
  777. char *afnp[];
  778. {
  779.     char pathname[PATHLEN];
  780.     int filecount,
  781.         baselen;
  782.     union REGS inregs;
  783.     union REGS outregs;
  784.     struct find_buf f_buf;
  785.  
  786.         /* extract directory name */
  787.     strcpy(pathname,afnp);
  788.         /* search backwards for directory separator */
  789.     for (baselen=strlen(pathname); baselen>=0; baselen--)
  790.     {
  791.         if (index(pathname[baselen],PATHSEP))
  792.             break;
  793.         pathname[baselen]=0;    
  794.     }
  795.     baselen++;
  796.  
  797.         /* DMA must point to f_buf structure */
  798.     bdos(SETDMA, &f_buf);
  799.         /* set pointer to file name */
  800.     inregs.x.dx = (short)afnp;
  801.         /* allow search for files and directorys */
  802.     inregs.x.cx = DIRAT;
  803.         /* find first DOS function */
  804.     inregs.h.ah = FINDFIRST;
  805.  
  806.     filecount = 0;
  807.     while(1)
  808.     {
  809.         intdos(&inregs,&outregs);
  810.             /* done?? */
  811.         if (outregs.x.ax == NOTFOUND)
  812.             break;
  813.  
  814.             /* indicate how many files were found */
  815.         filecount = filecount + 1;
  816.  
  817.             /* search command finds name of file, not full pathname.
  818.                send full path name along with file info */
  819.         strcat(pathname,f_buf.pname);
  820.         if((*fnx)(&f_buf,pathname)==ERROR)
  821.             return ERROR;
  822.  
  823.             /* reset pathname to directory name */
  824.         pathname[baselen]=0;
  825.  
  826.             /* after findfirst, rest must be findnext */
  827.         inregs.h.ah = FINDNEXT;
  828.     }
  829.  
  830.     if (filecount==0)
  831.     {
  832.         printf("'%s' NOT FOUND\n", afnp);
  833.         return ERROR;
  834.     }
  835.  
  836.     return OK;
  837. } /* e1xpand */
  838.  
  839.  
  840.  
  841. /****************************************************************************
  842. FUNCTION:
  843.     cisubstr(string, token) searches for lower case token in string s
  844.     returns pointer to token within string if found, NULL otherwise
  845.     ignore parity in strings s
  846.  
  847. CALLING PARAMETERS:
  848.     *s:
  849.         pointer to string
  850.     *t:
  851.         pointer to character token to search for
  852. ===========================================================================*/
  853. char *cisubstr(s, t)
  854. char *s,*t;
  855. {
  856.     char *ss,*tt;
  857.     /* search for first char of token */
  858.     for(ss=s; *s; s++)
  859.         if(tolower(*s & 0177)==*t)
  860.             /* compare token with substring */
  861.             for(ss=s,tt=t; ;)
  862.             {
  863.                 if(*tt==0)
  864.                     return s;
  865.                 if(tolower(*ss++ & 0177) != *tt++)
  866.                     break;
  867.             }
  868.     return NULL;
  869. } /* cisubstr */
  870.  
  871.  
  872. /****************************************************************************
  873. FUNCTION:
  874.     copy string s onto itself deleting spaces "hello there" > "hellothere"
  875.  
  876. CALLING PARAMETERS:
  877.     *s:
  878.         pointer to string
  879. ===========================================================================*/
  880. unspace(s)
  881. char *s;
  882. {
  883.     char *p;
  884.     for(p=s; *s; s++)
  885.         if(*s != ' ')
  886.             *p++ = *s;
  887.     *p++ =0;
  888. } /* unspace */
  889.  
  890.  
  891. #ifdef LOGFILE
  892. /****************************************************************************
  893. FUNCTION:
  894.     logfile keeps a record of files transmitted.
  895.  
  896. CALLING PARAMETERS:
  897.     *log:
  898.     *name:
  899.     mode:
  900. ===========================================================================*/
  901. logfile(log, name, mode)
  902. char *log, *name;
  903. char mode;
  904. {
  905.     int thedisk;
  906.     char *i;
  907.  
  908.     /* find out what disk was used */
  909.     thedisk=defdisk + 'a';
  910.     if(i=index(':', name))
  911.     {
  912.         thedisk = *name;
  913.         name= ++i;
  914.     }
  915.     if(i=index('\t', Phone))    /* keep just the system name */
  916.         *i = 0;
  917. #ifdef XMODEM
  918.     if(i=index('\r', Phone))    /* keep just user's name */
  919.         *i = 0;
  920.     if(i=index('\n', Phone))    /* keep just user's name */
  921.         *i = 0;
  922. #endif
  923.  
  924.     if(fin=fopen(log,"ab")!=NULL)
  925.     {
  926.         fprintf(fin, "%c %5u    %c:%-14s %s\n",
  927.          mode, Baudrate, thedisk, name, Phone);
  928.         putc(CPMEOF, fin);
  929.         fflush(fin);
  930.         fclose(fin);
  931.     }
  932. } /* logfile */
  933. #endif
  934.  
  935.  
  936. /****************************************************************************
  937. FUNCTION:
  938.     perform CRC calculation on a file
  939.     The generator is X^16 + X^12 + X^5 + 1 as recommended by CCITT.
  940.     This routine stops calculating CRC on EOF so it should have the
  941.     same numbers as its CPM counterpart.
  942.  
  943. CALLING PARAMETERS:
  944.     f_buf:
  945.         pointer to a structure containing information about file
  946.     *pathname:
  947.         pointer to directory path name
  948. ===========================================================================*/
  949. #ifdef BIGYAM
  950. crcfile(f_buf,pathname)
  951. struct find_buf *f_buf;
  952. char *pathname;
  953. {
  954.     printf("%-14s ",f_buf->pname);
  955.     oldcrc = 0;
  956.     if ((Utility.ufbuf=fopen(pathname,"rb"))==NULL)
  957.         return ERROR;
  958.  
  959.         /* read file and do crc calculation */
  960.     while ((firstch=getc(Utility.ufbuf))!=EOF)
  961.     {
  962.             /* crc calculation */
  963.         oldcrc = updcrc(firstch, oldcrc);
  964.     }
  965.  
  966.         /* complete crc calculation */
  967.     oldcrc=updcrc(0,updcrc(0,oldcrc));
  968.     fclose(Utility.ufbuf);
  969.     if(CIREADY)
  970.         return ERROR;
  971.  
  972.         /* display crc and file name */
  973.     printf("CRC = %04x\n", oldcrc);
  974.     return OK;
  975. } /* crcfile */
  976.  
  977.  
  978. /****************************************************************************
  979. FUNCTION:
  980.     perform CRC calculation on a file, or group of files
  981.  
  982. CALLING PARAMETERS:
  983.     argc:
  984.         integer count for number of argp's
  985.     argp:
  986.         pointer to pointer to arguments
  987. ===========================================================================*/
  988. docrc(argc, argp)
  989. char **argp;
  990. {
  991.     expand(crcfile, argc, argp);
  992. } /* docrc */
  993.  
  994.  
  995. /****************************************************************************
  996. FUNCTION:
  997.     perform CRCK calculation on one or a group of files
  998.  
  999. CALLING PARAMETERS:
  1000.     argc:
  1001.         integer count for number of argp's
  1002.     argp:
  1003.         pointer to pointer to arguments
  1004. ===========================================================================*/
  1005. docrck(argc, argp)
  1006. char **argp;
  1007. {
  1008.     int crckfile();
  1009.  
  1010.     expand(crckfile, argc, argp);
  1011. } /* docrck */
  1012.  
  1013.  
  1014. /****************************************************************************
  1015. FUNCTION:
  1016.     Accumulate and print a "crck" for a file
  1017.     CCITT standard polynominal:
  1018.     X^16 + X^15 + X^13 + X^7 + X^4 + X^2 + X + 1
  1019.     This routine stops when the EOF is read.  CPM versions always do the
  1020.     crc for an entire sector.  Some CRCK programs in CPM use this algorythm
  1021.     but generate numbers for data past EOF.  Therefore this routine
  1022.     will not generate same numbers unless file is exact multiple of sector
  1023.     size.
  1024.  
  1025. CALLING PARAMETERS:
  1026.     f_buf:
  1027.         pointer to a structure containing information about file
  1028.     *pathname:
  1029.         pointer to directory path name
  1030. ===========================================================================*/
  1031. crckfile(f_buf,pathname)
  1032. struct find_buf *f_buf;
  1033. char *pathname;
  1034. {
  1035.     unsigned crck();
  1036.     int fd, st;
  1037.  
  1038.     printf("%-14s ",f_buf->pname);
  1039.  
  1040.         /* level 1 io, open read only, raw mode */
  1041.     fd=open(pathname, (O_RDONLY | O_RAW));
  1042.     if( fd==ERROR )
  1043.         return ERROR;
  1044.  
  1045.         /* init crc */
  1046.     oldcrc=0;
  1047.  
  1048.         /* read a block */
  1049.     while((st=read(fd, Utility.ubuf, blklen)) > 0)
  1050.                 /* update CRCK */
  1051.             oldcrc=crck(Utility.ubuf, st, oldcrc);
  1052.  
  1053.     if (close(fd))
  1054.         printf("file I/O error\n");
  1055.     if(CIREADY)
  1056.         return ERROR;
  1057.  
  1058.         /* display CRC, number of records and file name */
  1059.     printf("CRCK = %04x\n", oldcrc);
  1060.     return OK;
  1061.  
  1062. } /* crckfile */
  1063. #endif
  1064.  
  1065.  
  1066. /****************************************************************************
  1067. FUNCTION:
  1068.     print number of free blocks on default disk
  1069.  
  1070. CALLING PARAMETERS:
  1071.     none.
  1072. ===========================================================================*/
  1073. printdfr()
  1074. {
  1075.         /* print number of free bytes.  add 1 to defdisk because 0 means
  1076.            currently logged disk to getfree */
  1077.     printf("%u kb Free on %c: ", getfree(defdisk+1), defdisk+'A');
  1078.  
  1079. } /* printdfr */
  1080.  
  1081.  
  1082. /****************************************************************************
  1083. FUNCTION:
  1084.     return total free kilobytes of disk
  1085.  
  1086. CALLING PARAMETERS:
  1087.     disk:
  1088.         drive number to find free space on. 0=defdisk,1=A,...
  1089. ===========================================================================*/
  1090. unsigned getfree(disk)
  1091. int disk;
  1092. {
  1093.     union REGS inregs;
  1094.     union REGS outregs;
  1095.     long fullsize;
  1096.  
  1097.         /* get disk free space function */
  1098.     inregs.h.ah = GETFREE;
  1099.  
  1100.         /* set drive number */ 
  1101.     inregs.x.dx = disk;
  1102.  
  1103.         /* dos request function */
  1104.     intdos(&inregs,&outregs);
  1105.     if (outregs.x.ax == 0xFFFF)
  1106.         printf("INVALID DISK\n");
  1107.  
  1108.         /* total space left in bytes */
  1109.     fullsize = (long)outregs.x.ax * (long)outregs.x.bx * (long)outregs.x.cx;
  1110.  
  1111.         /* return KBytes */
  1112.     return (unsigned)(fullsize/1000);
  1113.  
  1114. } /* getfree */
  1115.  
  1116.  
  1117. /****************************************************************************
  1118. FUNCTION:
  1119.     erase files specified by path name atr argp
  1120.  
  1121. CALLING PARAMETERS:
  1122.     argc:
  1123.         integer number of parameters at argp
  1124.     argp:
  1125.         pointer to a pointer to string of file names.
  1126. ===========================================================================*/
  1127. doerase(argc, argp)
  1128. char **argp;
  1129. {
  1130.     int erasefile();
  1131.  
  1132.     expand(erasefile, argc, argp);
  1133.     printdfr();
  1134.  
  1135. } /* doerase */
  1136.  
  1137.  
  1138. /****************************************************************************
  1139. FUNCTION:
  1140.     erase a single file from directory
  1141.  
  1142. CALLING PARAMETERS:
  1143.     f_buf:
  1144.         pointer to a structure containing information about file
  1145.     *pathname:
  1146.         pointer to directory path name
  1147. ===========================================================================*/
  1148. erasefile(f_buf,pathname)
  1149. struct find_buf *f_buf;
  1150. char *pathname;
  1151. {
  1152.         /* don't allow directorys to be erased */
  1153.     if (f_buf->attrib & DIRAT)
  1154.         return FALSE;
  1155.  
  1156.     printf("Erase %s (y/n/q)? ",f_buf->pname);
  1157.     switch(getopt())
  1158.     {
  1159.     case 'y':
  1160.         unlink(pathname);
  1161.     case 'n':
  1162.         putch('\n');
  1163.         return FALSE;
  1164.     }
  1165.     return ERROR;
  1166. } /* erasefile */
  1167.  
  1168.  
  1169. #ifdef BIGYAM
  1170. /****************************************************************************
  1171. FUNCTION:
  1172.     Sum bytes in file mod 2^16 discard CR and EOF+junk.  Displays
  1173.     sum and a sort of CRC for file 
  1174.  
  1175. CALLING PARAMETERS:
  1176.     f_buf:
  1177.         pointer to a structure containing information about file
  1178.     *pathname:
  1179.         pointer to directory path name
  1180. ===========================================================================*/
  1181. sumfile(f_buf,pathname)
  1182. struct find_buf *f_buf;
  1183. char *pathname;
  1184. {
  1185.     unsigned nbytes;
  1186.  
  1187.     oldcrc = 0;
  1188.     nbytes = 0;
  1189.     printf("%-14s ",pathname);
  1190.     
  1191.         /* try to open file for read.  Utility buff is used as scratch */
  1192.     if ((Utility.ufbuf=fopen(f_buf->pname,"rb"))==NULL)
  1193.     {
  1194.         fprintf(stderr, "Can't open %s\n", pathname);
  1195.         return ERROR;
  1196.     }
  1197.  
  1198.         /* successful open, do sum calc */
  1199.     for (; (cfast=getc(Utility.ufbuf))!=EOF && cfast!=0x1a; )
  1200.     {
  1201.         if (cfast=='\r')
  1202.             continue;
  1203.         ++nbytes;
  1204.  
  1205.             /* crc calculation */
  1206.         if (oldcrc&01)
  1207.             oldcrc = (oldcrc>>1) + 0x8000;
  1208.         else
  1209.             oldcrc >>= 1;
  1210.         oldcrc += cfast;
  1211.     }
  1212.  
  1213.     fclose(Utility.ufbuf);
  1214.     if(CIREADY)
  1215.         return ERROR;
  1216.  
  1217.         /* dipsplay crc, number of bytes */
  1218.     printf("CRC = %5u #bytes = %7u\n", oldcrc, nbytes);
  1219.     return OK;
  1220. } /* sumfile */
  1221.  
  1222.  
  1223. /****************************************************************************
  1224. FUNCTION:
  1225.     Sum bytes in file or group of files.  See sumfile.
  1226.  
  1227. CALLING PARAMETERS:
  1228.     argc:
  1229.         integer count for number of argp's
  1230.     argp:
  1231.         pointer to pointer to arguments
  1232. ===========================================================================*/
  1233. dosum(argc, argp)
  1234. char **argp;
  1235. {
  1236.     int sumfile();
  1237.     expand(sumfile, argc, argp);
  1238. } /* dosum */
  1239.  
  1240.  
  1241. /****************************************************************************
  1242. FUNCTION:
  1243.     count lines words bytes and carriage returns in file
  1244.  
  1245. CALLING PARAMETERS:
  1246.     f_buf:
  1247.         pointer to a structure containing information about file
  1248.     *pathname:
  1249.         pointer to directory path name
  1250. ===========================================================================*/
  1251. wcfile(f_buf,pathname)
  1252. struct find_buf *f_buf;
  1253. char *pathname;
  1254. {
  1255.     unsigned lines, words, ncr;
  1256.  
  1257.     if ((Utility.ufbuf=fopen(pathname,"rb"))==NULL)
  1258.         return ERROR;
  1259.     lines = words = firstch = ncr = checksum = 0;
  1260.     while(1)
  1261.     {
  1262.         cfast = getc(Utility.ufbuf);
  1263.         if (cfast == EOF || cfast == 0x1a)
  1264.             break;
  1265.         ++firstch;
  1266.         if (cfast>040 && cfast<0177)
  1267.         {
  1268.             if (!checksum)
  1269.             {
  1270.                 ++words;
  1271.                 ++checksum;
  1272.             }
  1273.             continue;
  1274.         }
  1275.         if (cfast=='\n')
  1276.             ++lines;
  1277.         else if (cfast=='\r')
  1278.             ++ncr;
  1279.         else if (cfast!=' ' && cfast!='\t')
  1280.             continue;
  1281.         checksum = 0;
  1282.     }
  1283.     fclose(Utility.ufbuf);
  1284.     if(CIREADY)
  1285.         return ERROR;
  1286.     printf("%7u lines,%7u words,%7u%7u %s\n",
  1287.          lines,words, firstch-ncr, firstch, f_buf->pname);
  1288.     return OK;
  1289. } /* wcfile */
  1290.  
  1291.  
  1292. /****************************************************************************
  1293. FUNCTION:
  1294.     entry point for word count.  Count lines words bytes and carriage
  1295.     returns in file
  1296.     
  1297. CALLING PARAMETERS:
  1298.     argc:
  1299.         count of parameters at argp
  1300.     argp:
  1301.         pointer to pointer to file name.
  1302. ===========================================================================*/
  1303. dowc(argc, argp)
  1304. char **argp;
  1305. {
  1306.     expand(wcfile, argc, argp);
  1307. } /* dowc */
  1308.  
  1309.  
  1310. /****************************************************************************
  1311. FUNCTION:
  1312.     dump a file in side by side hex-ascii format to crt
  1313.  
  1314. CALLING PARAMETERS:
  1315.     f_buf:
  1316.         pointer to a structure containing information about file
  1317.     *pathname:
  1318.         pointer to directory path name
  1319. ===========================================================================*/
  1320. dump(f_buf,pathname)
  1321. struct find_buf *f_buf;
  1322. char *pathname;
  1323. {
  1324.     int fd, st;
  1325.     char *val;
  1326.     unsigned i;    
  1327.     long startnum;
  1328.  
  1329.     printf("%-14s\n",f_buf->pname);
  1330.  
  1331.         /* level 1 io, open read only, raw mode */
  1332.     fd=open(pathname, (O_RDONLY | O_RAW));
  1333.     if( fd==ERROR )
  1334.         return ERROR;
  1335.  
  1336.         /* display a line at a time of the file */
  1337.     startnum = 0;
  1338.     while((st=read(fd, Utility.ubuf, 16)) > 0)
  1339.     {
  1340.             /* display in hex */
  1341.         val = (char *)Utility.ubuf;
  1342.         printf("%05lx  ",startnum);
  1343.         for(i=0; i<st; i++)
  1344.             printf("%02x ",*val++);
  1345.  
  1346.         while(i++ <= 16)
  1347.             printf("   ");
  1348.         printf("  ");
  1349.  
  1350.             /* display in ascii */
  1351.         val = (char *)Utility.ubuf;
  1352.         for(i=0; i<st; i++,val++)
  1353.             printf("%c",(*val&0x7f)>' '?(*val&0x7f):'.');
  1354.  
  1355.             /* to next line */
  1356.         startnum=startnum+16;
  1357.         putchar('\n');
  1358.         if(CIREADY)
  1359.             return ERROR;
  1360.     }
  1361.     if (close(fd))
  1362.         printf("file I/O error\n");
  1363.     return OK;
  1364. } /* dump */
  1365.  
  1366.  
  1367. /****************************************************************************
  1368. FUNCTION:
  1369.     do a hex-ascii dump of a file to srceen.
  1370.     
  1371. CALLING PARAMETERS:
  1372.     argc:
  1373.         count of parameters at argp
  1374.     argp:
  1375.         pointer to pointer to file name.
  1376. ===========================================================================*/
  1377. dodump(argc, argp)
  1378. char **argp;
  1379. {
  1380.     expand(dump, argc, argp);
  1381. } /* dodump */
  1382.  
  1383. #endif  /* if BIGYAM */
  1384.  
  1385.  
  1386. /****************************************************************************
  1387. FUNCTION:
  1388.     copy string at sourceptr to destptr, converting special escaped
  1389.     character sequences to their proper values.  This is used at initialization
  1390.     to read convert ascii strings from the configuration file
  1391.  
  1392. CALLING PARAMETERS:
  1393.     destptr:
  1394.         pointer to string to receive the formated data
  1395.     sourceptr:
  1396.         pointer to source ascii string which may contain escape sequences
  1397. ===========================================================================*/
  1398. sconfig(destptr,sourceptr)
  1399. char *destptr, *sourceptr;
  1400. {
  1401.     char *xptr;
  1402.  
  1403.         /* move to start of string */
  1404.     while(*sourceptr++ != '=');
  1405.  
  1406.         /* copy to local buffer and convert escaped strings */
  1407.     while(*sourceptr)
  1408.     {    
  1409.         if (*sourceptr == '\\')
  1410.         {
  1411.             sourceptr++;
  1412.  
  1413.                 /* carrige return */
  1414.             if (*sourceptr == 'n')
  1415.             {
  1416.                 *destptr++ = '\n';
  1417.                 sourceptr++;
  1418.             }
  1419.                 /* default to a hex number of format \0xnn */
  1420.             else
  1421.             {
  1422.                 sourceptr = sourceptr + 2;
  1423.                 sscanf(sourceptr,"%x",destptr++);
  1424.                 sourceptr = sourceptr + 2;
  1425.             }    
  1426.         }
  1427.         else if (*sourceptr == '\n')
  1428.             sourceptr++;
  1429.         else
  1430.         {
  1431.             *destptr++ = *sourceptr++;
  1432.         }
  1433.     }
  1434.     *destptr = '\0';
  1435.  
  1436. }/* sconfig */
  1437.  
  1438.  
  1439. /****************************************************************************
  1440. FUNCTION:
  1441.     read the configuration file a line at a time and copy it to local storage.
  1442.     This was implemented to allow strings which are frequently changed to be
  1443.     modified without re-compliation.  NOTE: the destination strings must
  1444.     be large enough to accept all the data from the configuration file.  NO
  1445.     length checking is done.  This routine causes the signon message to
  1446.     be displayed, and shows the current baud and port configuration.
  1447.  
  1448. CALLING PARAMETERS:
  1449.     buffer:
  1450.         pointer to scratch buffer to use when reading configuration file
  1451. ===========================================================================*/
  1452. read_config(buffer)
  1453. char *buffer;
  1454. {
  1455.  
  1456.     searchpath(YAMCONFIG,Utility.ubuf);
  1457.     if((fin=fopen(Utility.ubuf,"r"))==NULL)
  1458.     {
  1459.         printf("Cannot open %s\n", Utility.ubuf);
  1460.         return;
  1461.     }
  1462.     else
  1463.     {
  1464.             /* read config file a line at a time */
  1465.         while(fgets(buffer, 80, fin))
  1466.         {
  1467.         
  1468.             /* ignore null lines and those with a ';' as the
  1469.                    first character */
  1470.             if( (*buffer != ';') && (*buffer != '\n') )            
  1471.             {
  1472.                     /* set default port configuration(Baudrate, parity,etc */
  1473.                 if(strncmp("PORTINIT",buffer,8)==0)
  1474.                     setparams(buffer);
  1475.  
  1476.                     /* display signon strings */
  1477.                 else if( (strncmp("FLAVOR",buffer,6)==0) ||
  1478.                          (strncmp("REVISION",buffer,8)==0) )
  1479.                 {
  1480.                     sconfig(Utility.ubuf,buffer);
  1481.                     printf("%s",Utility.ubuf);
  1482.                 }
  1483.  
  1484.                     /* characters to ignore */
  1485.                 else if(strncmp("RXNONO",buffer,6)==0)
  1486.                     sconfig(rxnono,buffer);
  1487.  
  1488.                     /* xon string */
  1489.                 else if(strncmp("XON",buffer,3)==0)
  1490.                 {
  1491.                     sconfig(Utility.ubuf,buffer);
  1492.                     xon = Utility.ubuf[0];
  1493.                 }
  1494.  
  1495.                     /* xoff string */
  1496.                 else if(strncmp("XOFF",buffer,4)==0)
  1497.                 {
  1498.                     sconfig(Utility.ubuf,buffer);
  1499.                     xoff = Utility.ubuf[0];
  1500.                 }
  1501.  
  1502.                 else
  1503.                     printf("\n%sBad command in configuration file\n",buffer);
  1504.             }
  1505.         }
  1506.     }
  1507.     fclose(fin);
  1508. }/* read_config */
  1509.  
  1510.  
  1511. /****************************************************************************
  1512. FUNCTION:
  1513.     Perform various operating system dependent initializations that should
  1514.     be performed but once.
  1515.  
  1516. CALLING PARAMETERS:
  1517.     none
  1518. ===========================================================================*/
  1519. onceonly()
  1520. {
  1521.     bufst = (char *)malloc(10000);
  1522.     if (bufst==NULL)
  1523.     {
  1524.         printf("insufficent memory");
  1525.         exit(1);
  1526.     }
  1527.     bufend = bufst + 10000;
  1528.     T1pause=290*CLKMHZ;    /* calibration for deciseconds in readbyte() */
  1529.  
  1530. #ifdef IBMPC
  1531.         /* set up comm interrupt.  Tell it the lowwater mark where 
  1532.            and point where ^s will be sent */
  1533.     init_com(LOWWATER);
  1534.  
  1535.         /* set default port.  Needed by chgport for first time thru */
  1536.     commport = 0;
  1537.     Dport = DPORT;
  1538.  
  1539. #endif
  1540. } /* onceonly */
  1541.  
  1542.  
  1543. /****************************************************************************
  1544. FUNCTION:
  1545.     init resets all variables to their "standard" values (whatever that
  1546.     is ...).  Init is called at the beginning of yam and when the "init"
  1547.     command is given.
  1548.  
  1549. CALLING PARAMETERS:
  1550.     none
  1551. ===========================================================================*/
  1552. init()
  1553. {
  1554.         /* init user terminal */
  1555.     terminit();
  1556.  
  1557.         /* default xon-xoff, incase config file messed up */
  1558.     xon = 0x11; /* ^q */
  1559.     xoff = 0x13; /* ^s */
  1560.  
  1561.     tabstop = TABS;
  1562.     Mstatus=0;    
  1563.     Rfile=Tfile=Pflag=FALSE;
  1564. #ifdef Cis02
  1565.     Cis02=FALSE;
  1566. #endif
  1567.     Waitbunch=Exoneof=Hdx=Zeof=Squelch=FALSE;
  1568.     Txgo=TRUE;
  1569.     Originate= TRUE;
  1570.     Txeoln= EOL_NOTHING;
  1571.     Tpause=1500*CLKMHZ;
  1572.     Throttle=22*CLKMHZ;
  1573.     Waitnum=1;
  1574.     GOchar= '\n';
  1575.  
  1576.         /* init buffer pointers.  This must be done before any access to
  1577.            modem.  If not characters gotten from the interrupt routine
  1578.            will be placed in random locations */
  1579.     clearbuff();
  1580.  
  1581.         /* get default disk */
  1582.     defdisk = bdos(GETDEFDISK,0);
  1583.  
  1584. #ifdef XMODEM
  1585.     if((fin=fopen(LASTCALR,"rb"))!=NULL)
  1586.     {
  1587.         fgets(Phone, 100, fin);
  1588.         fclose(fin);
  1589.     }
  1590. #endif
  1591.  
  1592.         /* read config file, used phoneline buffer as scratch */
  1593.     read_config(Phone);
  1594.  
  1595.         /* initialize Phone to blank line */
  1596.     Phone[0] = 0;
  1597.  
  1598.         /* set up default port number to use */
  1599.     chngport(0);
  1600.  
  1601.         /* allows extra user externs to be initialized */
  1602.     userinit(FALSE);
  1603.  
  1604. } /* init */
  1605.  
  1606.  
  1607. /****************************************************************************
  1608. FUNCTION:
  1609.     pause n 1/10s of a sec.  NOTE: this is implemented as a software loop
  1610.     and will be compiler and processor dependent
  1611.  
  1612. CALLING PARAMETERS:
  1613.     n:
  1614.         number of 1/10s of a sec to pause
  1615. ===========================================================================*/
  1616. sleep(n)
  1617. int n;
  1618. {
  1619.     int i,j;
  1620.     for(i=0; i<n; i++)
  1621.         for(j=0; j<(LOOPS); j++);
  1622. } /* sleep */
  1623.